use std::{fmt, sync::Arc};

use askama::Template;
use axum::{Json, response::Html};
use serde::{Deserialize, Serialize};

use crate::{AppState, mov::Mov};

pub async fn video_h(state: axum::extract::State<Arc<AppState>>) -> Html<String> {
    let play_urls = parse_play_urls(&state.video_data.lock().await.vod_play_url);
    let template = VideoTemplate {
        video: state.video_data.lock().await.clone(),
        play_urls,
    };
    Html(template.render().unwrap())
}

pub async fn video_post(
    state: axum::extract::State<Arc<AppState>>,
    movinfo: Json<Mov>,
) -> Json<Mov> {
    // println!("{:#?}", movinfo);
    let mut videos = state.video_data.lock().await;
    *videos = movinfo.0.clone();
    movinfo
}

// 解析播放URL
fn parse_play_urls(play_url: &str) -> Vec<(String, String)> {
    play_url
        .split('#')
        .filter_map(|part| {
            let parts: Vec<&str> = part.splitn(2, '$').collect();
            if parts.len() == 2 {
                Some((parts[0].to_string(), parts[1].to_string()))
            } else {
                None
            }
        })
        .collect()
}

// 模板结构体
#[derive(Template)]
#[template(path = "video.html")]
struct VideoTemplate {
    video: Mov,
    play_urls: Vec<(String, String)>,
}

/// m3u8列表
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Playlist {
    /// 本集名称
    pub name: String,
    /// 本集hls地址
    pub url: String,
}

// 实现 Error trait
impl std::error::Error for Playlist {}
// 实现 Display trait 以方便打印错误信息
impl fmt::Display for Playlist {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.name)
    }
}
